{-# OPTIONS -Wall #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  OchreLang.CheckInter
-- Copyright   :  (c) Stephen Tetley 2014
-- License     :  BSD3
--
-- Maintainer  :  stephen.tetley@gmail.com
-- Stability   :  unstable
-- Portability :  GHC
--
-- Checker working on Syntax.
--
--------------------------------------------------------------------------------

module OchreLang.CheckInter
  (
   
    allBound

  ) where

import OchreLang.CompilerMon
import OchreLang.Syntax
import OchreLang.SyntaxBase

import Control.Monad
import qualified Data.Set as Set
import Text.Printf


allBound :: Instrument -> Compiler ()
allBound (Instrument { instr_main = main_expr}) = allBoundExpr main_expr

-- | Prior to translation to Csound, the main expression should 
-- have no free variables...
-- 
allBoundExpr :: Expr -> Compiler ()
allBoundExpr e1 = 
    let fvs   = freevars e1  
        calls = primIds e1
    in do { when (not $ Set.null fvs) (errorFreevars fvs)
          ; builts <- askBuiltinNames 
          ; let fcalls = foldr Set.delete calls builts
          ; when (not $ Set.null fcalls) (errorPrimcalls fcalls)
          }

  where
    errorFreevars fvs  = throwError "CheckInter.allBound" 
                                    (printf "Free variables present in main: %s"
                                            (show $ map ppVarId $ Set.toList fvs))

    errorPrimcalls fvs = throwError "CheckInter.allBound" 
                                    (printf "Unrecognized csound opcodes: %s"
                                            (show $ map ppIdent $ Set.toList fvs))

